package org.shop.controller.app;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.shop.dao.UsersMapper;
import org.shop.entity.LoginRecord;
import org.shop.entity.School;
import org.shop.entity.Users;
import org.shop.entity.UsersLoginVO;
import org.shop.entity.security.MyUserDetail;
import org.shop.service.LoginRecordService;
import org.shop.service.SchoolService;
import org.shop.service.UserService;
import org.shop.util.CommonUtil;
import org.shop.util.DateUtils;
import org.shop.util.HttpClientUtil;
import org.shop.util.JsonUtils;
import org.shop.util.MD5Util;
import org.shop.util.ObjUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class RegisterController {
	private static Logger logger = LogManager.getLogger(RegisterController.class);

	@Autowired
	private UserService userService;
	@Autowired
	private SchoolService schoolService;
	@Autowired
	private LoginRecordService loginRecordService;
	@Autowired
    protected AuthenticationManager authenticationManager;
	@Autowired
	private UserDetailsService userDetailsService;
	@Autowired
	private UsersMapper usersMapper;
	/**
	 * 跳转app注册页面
	 * @param req
	 * @return
	 * @throws IOException 
	 */
	@RequestMapping("app/appRegister")
	public String appRegister(HttpServletRequest req,HttpServletResponse res) throws IOException{
		return "app/appRegister";
	}
	
	/**
	 * 学生注册
	 * @param req
	 * @return
	 */
	@RequestMapping("app/appRegister2")
	@ResponseBody
	public Map<String, Object> appRegister2(HttpServletRequest req){
		Map<String, Object> map = new HashMap<String, Object>();
		String phone = req.getParameter("phone");
		String password = req.getParameter("password");
		String volatileCode = req.getParameter("volatileCode");
		String schoolId = req.getParameter("schoolId");
		try {
			HttpSession session=req.getSession(false);
			Integer tempVolatileCode=(Integer) session.getAttribute(phone);
			
			UsersLoginVO usersLoginVO = (UsersLoginVO)session.getAttribute("usersLoginVO");
			
			Users users=userService.findUserByLoginName(phone);
			if(ObjUtil.isNotNullAndEmpty(users)){
				map.put("state", -2);
	            map.put("msg", "手机号已经存在");
	            return map;
			}
			if(volatileCode.equals(tempVolatileCode+"")){
				Users user = new Users();
				user.setLoginName(phone);
				user.setPhone(phone);
				user.setPassword(MD5Util.MD5(password));
				user.setSchoolId(Long.parseLong(schoolId));
				user.setUserType((long) 0);
				user.setUserName(phone);
				//第三方数据
				if(ObjUtil.isNotNullAndEmpty(usersLoginVO)) {
					user.setUserName(usersLoginVO.getUserName());
					user.setStudentNo(usersLoginVO.getStudentNo());
					user.setRealName(usersLoginVO.getName());
					user.setPhone(usersLoginVO.getPhone());
					
					School school=schoolService.getSchoolBySchoolCode(usersLoginVO.getSchoolName());
					if(ObjUtil.isNotNullAndEmpty(school)) {
						school.setSchoolName(usersLoginVO.getSchoolName());
						schoolService.updateByPrimaryKeySelective(school);
					}else {
						school=new School();
						school.setSchoolName(usersLoginVO.getSchoolName());
						schoolService.insertSelective(school);
					}
				}
				userService.insertSelective(user);
				
				UsernamePasswordAuthenticationToken token=new UsernamePasswordAuthenticationToken(user.getPhone(),password);
                token.setDetails(new WebAuthenticationDetails(req));
                Authentication authenticatedUser=authenticationManager.authenticate(token);
                SecurityContextHolder.getContext().setAuthentication(authenticatedUser);
                req.getSession().setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, SecurityContextHolder.getContext());
                
				map.put("state", 1);
	            map.put("msg", "注册成功");
			}else{
				map.put("state", -1);
	            map.put("msg", "验证码不正确");
			}
		} catch(Exception e) {
			e.printStackTrace();
			logger.error(e);
			map.put("state", 0);
            map.put("msg", "注册失败");
		}
		
		return map;
	}
	
	/**
	 * 获取验证码
	 * @param req
	 * @return
	 */
	@RequestMapping("app/getAppVolatileCode")
	@ResponseBody
	public Map<String, Object> getAppVolatileCode(HttpServletRequest req, Model model){
		Map<String, Object> retMap=new HashMap<String, Object>();
		try{
			String phone=req.getParameter("phone");
			int random=(int)((Math.random()*9+1)*100000);
			HttpSession session=req.getSession(false);
			if(session != null) {
				session.setAttribute(phone, random);
			}
			String smsUrl=CommonUtil.getPropertiesParam("smsUrl");
			String account=CommonUtil.getPropertiesParam("account");
			String password=CommonUtil.getPropertiesParam("password");
			Map<String, Object> map=new HashMap<String, Object>();
			map.put("account", account);
			map.put("password", password);
			map.put("phone", phone);
			map.put("msg", "验证码："+random);
			String bodyJson=HttpClientUtil.doPostJson(smsUrl, JsonUtils.toJson(map));
			String code=JsonUtils.fromJson(bodyJson).get("code").asText();
			if(code.equals("0")){
				retMap.put("state", 1);
				retMap.put("msg", "操作成功");
			}else{
				retMap.put("state", 0);
				retMap.put("msg", "操作失败");
			}
		}catch(Exception e){
			e.printStackTrace();
			logger.error(e);
			retMap.put("state", 0);
			retMap.put("msg", "操作失败");
		}
		return retMap;
	}
	
	/**
	 * app账号登录
	 * @param req
	 * @return
	 * @throws IOException 
	 */
	@RequestMapping("app/appLogin2")
	public String appLogin2(HttpServletRequest req,HttpServletResponse res) throws IOException{
		if (req.getHeader("x-requested-with") != null  
                && req.getHeader("x-requested-with").equalsIgnoreCase(  
                "XMLHttpRequest")) { // ajax 超时处理  
			res.setHeader("sessionstatus", "login");  
			res.setHeader("sessionstatus", "timeout");  
            Map<String, Object> error = new HashMap<String, Object>();  
            error.put("success", false);  
            error.put("sessionStatus", "timeout");  
            PrintWriter printWriter=res.getWriter();  
            printWriter.write(JsonUtils.toJson(error));  
            printWriter.flush();  
            printWriter.close();  
        }
		return "app/appLogin";
	}
	
	/**
	 * 校验账号是否存在
	 * @param req
	 * @return
	 */
	@RequestMapping("app/verifyLoginName")
	@ResponseBody
	public Map<String, Object> verifyLoginName(HttpServletRequest req){
		Map<String, Object> map = new HashMap<String, Object>();
		String phone = req.getParameter("phone");
		Users users=userService.findUserByLoginName(phone);
		if(ObjUtil.isNotNullAndEmpty(users)) {
			map.put("state", 1);
            map.put("msg", "账号已存在");
		}else {
			map.put("state", 0);
            map.put("msg", "账号不存在，请先注册");
		}
		return map;
	}
	
	/**
	 * 忘记密码
	 * @param req
	 * @return
	 */
	@RequestMapping("app/forgetPassword")
	@ResponseBody
	public Map<String, Object> forgetPassword(HttpServletRequest req){
		Map<String, Object> map = new HashMap<String, Object>();
		String phone = req.getParameter("phone");
		String password = req.getParameter("password");
		String volatileCode = req.getParameter("volatileCode");
		String schoolId = req.getParameter("schoolId");
		try {
			HttpSession session=req.getSession(false);
			Integer tempVolatileCode=(Integer) session.getAttribute(phone);
			
			Users users=userService.findUserByLoginName(phone);
			
			if(volatileCode.equals(tempVolatileCode+"")){
				users.setPassword(MD5Util.MD5(password));
				if(ObjUtil.isNotNullAndEmpty(users)) {
					userService.updateByPrimaryKeySelective(users);
					UsernamePasswordAuthenticationToken token=new UsernamePasswordAuthenticationToken(phone,password);
					token.setDetails(new WebAuthenticationDetails(req));
					Authentication authenticatedUser=authenticationManager.authenticate(token);
					SecurityContextHolder.getContext().setAuthentication(authenticatedUser);
					req.getSession().setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, SecurityContextHolder.getContext());
					
					map.put("state", 1);
		            map.put("msg", "密码修改成功");
				}else {
					map.put("state", 2);
		            map.put("msg", "请先注册");
				}
				
			}else{
				map.put("state", -1);
	            map.put("msg", "验证码不正确");
			}
		} catch(Exception e) {
			e.printStackTrace();
			logger.error(e);
			map.put("state", 0);
            map.put("msg", "密码修改失败");
		}
		
		return map;
	}
	
	/**
	 * 远程授权登录
	 * @param req
	 * @param usersLoginVO
	 * @return
	 */
	@RequestMapping("app/appLogin")
	@ResponseBody
	public Map<String, Object> appLogin(HttpServletRequest req,@RequestBody UsersLoginVO usersLoginVO){
		Map<String, Object> retMap=new HashMap<String, Object>();
		String password = "123456";
		String userName = usersLoginVO.getUserName();
		String url = "http://" + req.getServerName() + ":"+ req.getServerPort()+ req.getContextPath()+"/app/appIndex";
		try{
			HttpSession session=req.getSession();
			session.setAttribute("usersLoginVO", usersLoginVO);
			Users users1 = usersMapper.findUserByLoginName(userName);
			if(users1==null) {
				Users users = new Users();
				users.setLoginName(userName);
				users.setPassword(MD5Util.MD5(password));
				users.setUserType((long) 0);
				users.setSchoolId((long) 1);
				users.setPhone(usersLoginVO.getPhone());
				int num = userService.insertSelective(users);
				if(num > 0) {
				   UserDetails loadUserByUsername = userDetailsService.loadUserByUsername(userName);
			       UsernamePasswordAuthenticationToken token=new UsernamePasswordAuthenticationToken(userName,password);
			       token.setDetails(new WebAuthenticationDetails(req));
			       Authentication authenticatedUser=authenticationManager.authenticate(token);
			       SecurityContextHolder.getContext().setAuthentication(authenticatedUser);
				  req.getSession().setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, SecurityContextHolder.getContext());
					if(loadUserByUsername!=null&&!"".equals(loadUserByUsername)) {
						retMap.put("successUrl", url);
						retMap.put("state", 1);
						retMap.put("msg", "请求成功");
					}else {
						retMap.put("msg", "请求失败");
						retMap.put("state", 0);
					}
				}else {
					retMap.put("msg", "请求失败");
					retMap.put("state", 0);
				}
			}else {
				  UserDetails loadUserByUsername = userDetailsService.loadUserByUsername(userName);
				  UsernamePasswordAuthenticationToken token=new UsernamePasswordAuthenticationToken(userName,password);
				  token.setDetails(new WebAuthenticationDetails(req));
				  Authentication authenticatedUser=authenticationManager.authenticate(token);
				  SecurityContextHolder.getContext().setAuthentication(authenticatedUser);
				  req.getSession().setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, SecurityContextHolder.getContext());
				if(loadUserByUsername!=null&&!"".equals(loadUserByUsername)) {
					retMap.put("successUrl", url);
					retMap.put("msg", "请求成功");
					retMap.put("state", 1);
				}else {
					retMap.put("msg", "请求失败");
					retMap.put("state", 0);
				}
			}
		}catch(Exception e){
			e.printStackTrace();
			logger.error(e);
			retMap.put("state", 0);
			retMap.put("msg", "请求失败");
		}
		return retMap;
	}
	
	/**
	 * 重定向跳转到appindex顺带插入登录记录
	 * @return
	 */
	@RequestMapping("app/toAppIndexInsertAppLoginRecord")
	public String toAppIndexInsertAppLoginRecord(HttpServletRequest req) {
		Map<String,Object> paramMap = new HashMap<String,Object>();
		try {
			//获取登录人用户信息
			MyUserDetail ud = null;
			if(ObjUtil.isNotNullAndEmpty(SecurityContextHolder.getContext().getAuthentication())) {
				ud = (MyUserDetail) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
			}
			DateUtils du = new DateUtils();
			if(ObjUtil.isNotNullAndEmpty(ud)) {
				paramMap.put("userId", ud.getUserId());
			}
			paramMap.put("endTime", du.getLastYear());
			loginRecordService.delLoginRecordOfYearByUserId(paramMap);
			LoginRecord loginRecordInfo = new LoginRecord();
			if(ObjUtil.isNotNullAndEmpty(ud)) {
				loginRecordInfo.setUserId(ud.getUserId());
			}
			loginRecordInfo.setLoginIp(getIpAddress(req));
			loginRecordInfo.setLoginRemark(ud.getUsername()+"app登录");
			loginRecordInfo.setLoginType((byte) 0);
			loginRecordInfo.setLoginSrc((byte) 2);
			loginRecordService.insertSelective(loginRecordInfo);
		}catch(Exception e) {
			e.printStackTrace();
			logger.error(e.getMessage());
		}
		return "redirect:/app/appIndex";
	}
	
	/**
	 * 第三方登录接口
	 * @param req
	 * @return
	 */
//	@RequestMapping("app/appLogin")
//	@ResponseBody
//	public Map<String, Object> appLogin(HttpServletRequest req,@RequestBody UsersLoginVO usersLoginVO){
//		Map<String, Object> retMap=new HashMap<String, Object>();
//		try{
//			HttpSession session=req.getSession(false);
//			session.setAttribute("usersLoginVO", usersLoginVO);
//			logger.trace("接收参数"+JsonUtils.toJson(usersLoginVO));
//			if(StringUtils.isEmpty(usersLoginVO.getUserId())){
//				retMap.put("state", 0);
//				retMap.put("msg", "参数正确，用户唯一标识不能为空");
//				return retMap;
//			}
//			if(StringUtils.isEmpty(usersLoginVO.getUserName())){
//				retMap.put("state", 0);
//				retMap.put("msg", "参数正确，用户登录名不能为空");
//				return retMap;
//			}
//			if(StringUtils.isEmpty(usersLoginVO.getStudentNo())){
//				retMap.put("state", 0);
//				retMap.put("msg", "参数正确，学号不能为空");
//				return retMap;
//			}
//			if(StringUtils.isEmpty(usersLoginVO.getName())){
//				retMap.put("state", 0);
//				retMap.put("msg", "参数正确，姓名不能为空");
//				return retMap;
//			}
//			if(StringUtils.isEmpty(usersLoginVO.getPhone())){
//				retMap.put("state", 0);
//				retMap.put("msg", "参数正确，联系电话不能为空");
//				return retMap;
//			}
//			if(StringUtils.isEmpty(usersLoginVO.getSex())){
//				retMap.put("state", 0);
//				retMap.put("msg", "参数正确，性别不能为空");
//				return retMap;
//			}
//			if(StringUtils.isEmpty(usersLoginVO.getSchoolId())){
//				retMap.put("state", 0);
//				retMap.put("msg", "参数正确，学校标识不能为空");
//				return retMap;
//			}
//			if(StringUtils.isEmpty(usersLoginVO.getSchoolName())){
//				retMap.put("state", 0);
//				retMap.put("msg", "参数正确，学校名称不能为空");
//				return retMap;
//			}
//			Users users =userService.findUserByStudentCode(usersLoginVO.getUserId());
//			if(users==null){
//				users=new Users();
//				users.setStudentCode(usersLoginVO.getUserId());
//				users.setUserType(0l);
//				users.setLoginName(usersLoginVO.getUserName());
//				users.setStudentNo(usersLoginVO.getStudentNo());
//				users.setRealName(usersLoginVO.getName());
//				users.setUserName(usersLoginVO.getNickname());
//				users.setPhone(usersLoginVO.getPhone());
//				users.setIdNo(usersLoginVO.getCertNo());
//				if("1".equals(usersLoginVO.getSex())){
//					users.setUserSex("男");
//				}else if("2".equals(usersLoginVO.getSex())){
//					users.setUserSex("女");
//				}else{
//					retMap.put("state", 0);
//					retMap.put("msg", "参数正确，性别参数不正确");
//					return retMap;
//				}
//				users.setNation(usersLoginVO.getNation());
//				School school=schoolService.getSchoolBySchoolCode(usersLoginVO.getSchoolId());
//				if(school==null){
//					school=new School();
//					school.setSchoolCode(usersLoginVO.getSchoolId());
//					school.setSchoolName(usersLoginVO.getSchoolName());
//					schoolService.insertSelective(school);
//				}else{
//					school.setSchoolName(usersLoginVO.getSchoolName());
//					schoolService.updateByPrimaryKeySelective(school);
//				}
//				users.setSchoolId(school.getSchoolId());
//				userService.insertSelective(users);
//			}else{
//				users.setStudentCode(usersLoginVO.getUserId());
//				users.setUserType(0l);
//				users.setLoginName(usersLoginVO.getUserName());
//				users.setStudentNo(usersLoginVO.getStudentNo());
//				users.setRealName(usersLoginVO.getName());
//				users.setUserName(usersLoginVO.getNickname());
//				users.setPhone(usersLoginVO.getPhone());
//				users.setIdNo(usersLoginVO.getCertNo());
//				if("1".equals(usersLoginVO.getSex())){
//					users.setUserSex("男");
//				}else if("2".equals(usersLoginVO.getSex())){
//					users.setUserSex("女");
//				}else{
//					retMap.put("state", 0);
//					retMap.put("msg", "参数正确，性别参数不正确");
//					return retMap;
//				}
//				users.setNation(usersLoginVO.getNation());
//				School school=schoolService.getSchoolBySchoolCode(usersLoginVO.getSchoolId());
//				if(school==null){
//					school=new School();
//					school.setSchoolCode(usersLoginVO.getSchoolId());
//					school.setSchoolName(usersLoginVO.getSchoolName());
//					schoolService.insertSelective(school);
//				}else{
//					school.setSchoolName(usersLoginVO.getSchoolName());
//					schoolService.updateByPrimaryKeySelective(school);
//				}
//				userService.updateByPrimaryKeySelective(users);
//			}
//			retMap.put("state", 1);
//			retMap.put("msg", "操作成功");
//		}catch(Exception e){
//			logger.error(e);
//			retMap.put("state", 0);
//			retMap.put("msg", "操作失败");
//		}
//		return retMap;
//	}
	
	
	
	 /** 
     * 获取用户真实IP地址，不使用request.getRemoteAddr();的原因是有可能用户使用了代理软件方式避免真实IP地址, 
*  
     * 可是，如果通过了多级反向代理的话，X-Forwarded-For的值并不止一个，而是一串IP值，究竟哪个才是真正的用户端的真实IP呢？ 
     * 答案是取X-Forwarded-For中第一个非unknown的有效IP字符串。 
     *  
     * 如：X-Forwarded-For：192.168.1.110, 192.168.1.120, 192.168.1.130, 
     * 192.168.1.100 
     *  
     * 用户真实IP为： 192.168.1.110 
     *  
     * @param request 
     * @return 
     */  
    public static String getIpAddress(HttpServletRequest request) {  
    	String ip = request.getHeader("x-forwarded-for");  
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
            ip = request.getHeader("Proxy-Client-IP");  
        }  
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
            ip = request.getHeader("WL-Proxy-Client-IP");  
        }  
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
            ip = request.getHeader("HTTP_CLIENT_IP");  
        }  
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");  
        }  
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
            ip = request.getRemoteAddr();  
        }  
        return ip;  
    } 
	
}
